using System;
using CStock;
using CUtil;
using System.IO;
using System.Diagnostics;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;

using System.Data;
using CIndicators;


namespace CStock
{

    //[System.Xml.Serialization.XmlRootAttribute("TradeCondition", Namespace="", IsNullable=false)]
    public class TradeEconomy : Trader, ITradeEconomy
    {
        #region private members

        //the ID will always be this one!!
        private const string tradeEconomyName = "CentralBank";
        private ITradeEconomyProfile tradeEconomyProfile;
        private DateTime date_Current;
        private DateTime date_Start;
       
        private string excelFileName;



        private INewsCollection newsCollection;

        ArrayList orderAssetsSell = new ArrayList();
        ArrayList orderAssetsBuy = new ArrayList();
        ArrayList orderDepositSell = new ArrayList();
        ArrayList orderDepositBuy = new ArrayList();
        IOrders orderStocks = new Orders();
        

        ITraders traders;
        
        private DataTable statusReport;
        int dateIndex = -1;
        IEconomyStatusCollection economyStatusCollection;
        double marginInterestSell = 0F;
        double marginInterestBuy = 0F;
        double marginBidSell = 0F;
        double marginBidBuy = 0.0F;
        DataTable orderBookTable;

        //ITrader trader_Selected;
        #endregion

        #region constructor

        public TradeEconomy()
        {
            try
            {

                this.iD = tradeEconomyName;
               
                date_Current = DateTime.Today;

                //--------------------------

                SetInstanceForStaticIndicators();

                //ProgramContext dh = ProgramContext.Instance;

                ResetPathFromConfiguration();
                this.traders = new Traders();
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error initializing Economy " + ex.Message);

            }

        }
        #endregion

        #region implementations

        private void SetInstanceForStaticIndicators()
        {
            //--------------------------
            //set variables for all static indicators:
            IIndicatorEconomyGlobal ind = InterestCB.Instance;
            ind.TradeEconomy = this;
            IIndicatorEconomyGlobal ind1 = NewsYield.Instance;
            ind1.TradeEconomy = this;

        }
        public override bool ResetPathFromConfiguration()
        {
            //base.ResetPath(newPath);

            ProgramContext pc = ProgramContext.Instance;
            Debug.Assert(pc != null);
            if (pc != null)
                this.path = pc.Configuration.Directories.TradeEconomyPath;
            return true;

        }
        #endregion

        #region ITradeEconomy Members

        public override string ID
        {
            get
            {
                return tradeEconomyName;
            }
            set
            {
                //Debug.Assert(false, "Cannot set the ID for tradeEcononmy - this is fixed");
                //ignore !!
            }
        }

        [Category("Trade\\Current"), DescriptionAttribute("ClassInstance")]
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public ITradeEconomyProfile TradeEconomyProfile
        {
            get
            {
                return this.tradeEconomyProfile;
            }
            set
            {
                this.tradeEconomyProfile = value;

            }
        }
        [Category("Economy\\Current"), DescriptionAttribute("DateTime")]
        public DateTime Date_Current
        {
            get
            {
                return this.date_Current;
            }
            set
            {
                this.date_Current = value;

            }
        }
        [Category("Economy\\Current"), DescriptionAttribute("DateTime")]
        public DateTime Date_Start
        {
            get
            {
                return this.date_Start;
            }
            set
            {
                this.date_Start = value;

            }
        }


  

        // [Category("Economy\\Current")]
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public IEconomyStatus EconomyStatus_Current
        {
            get
            {
                IEconomyStatus esCurrent = null;
                if (this.economyStatusCollection != null && this.economyStatusCollection.Items.Count > 0)
                {
                    IEconomyStatus es = this.economyStatusCollection.Items[0] as EconomyStatus;
                    esCurrent = es;
                    DateTime dtMin = es.Date;
                   
                    int indexMin = 0;

                    for (int i = 1; i < this.economyStatusCollection.Items.Count; i++)
                    {
                        es = this.economyStatusCollection.Items[i] as EconomyStatus;
                        if ( es.Date <= this.date_Current)
                        {
                            if (es.Date > dtMin)
                            {
                                dtMin = es.Date;
                                indexMin = i;
                            }
                        }
                        else
                        {
                            esCurrent = this.economyStatusCollection.Items[indexMin] as EconomyStatus;
                            return esCurrent;
                            

                        }

                    }
                }
                return esCurrent;
                
            }
           
        }



        [System.Xml.Serialization.XmlIgnoreAttribute()]
        ITraders ITradeEconomy.Traders
        {
            get
            {
                return this.traders;
            }
            set
            {
                traders = value;
            }
        }

        public bool DefaultPortfolios_Share()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public bool DefaultPortfolios_Bonds()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public bool Default_Traders()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        bool ITradeEconomy.SetTradeOrders()
        {
            throw new Exception("The method or operation is not implemented.");
        }


        #endregion

        #region general properties - methods

        public static ITrader GetTraderByID(string traderID)
        {
            ITradeEconomy tradeEconomyInstance = ProgramContext.Instance.TradeEconomy;

            if (traderID == tradeEconomyInstance.ID)
                return tradeEconomyInstance;

            for (int i = 0; i < tradeEconomyInstance.Traders.Items.Count; i++)
            {
                if (tradeEconomyInstance.Traders[i].ID == traderID)
                {
                    return tradeEconomyInstance.Traders[i];
                }
            }
            Debug.Assert(false, "Orders: No trader with ID could be found : " + traderID);
            return null;
        }
        public static IList<string> GetAllShares()
        {
            IList<string> allShares = new List<string>();
            for (int i = 0; i < ProgramContext.Instance.TradeEconomy.Portfolios.Items.Count; i++)
            {
                IPortfolio portf = ProgramContext.Instance.TradeEconomy.Portfolios.Items[i] as IPortfolio;
                for (int j = 0; j < portf.DataItems.Count; j++)
                {
                    IDataItem di = portf.DataItems[j];
                    allShares.Add(di.ID);

                }

            }
            return allShares;
        }
        public static new IPortfolio GetPortfolioByID(string portID)
        {
            ITradeEconomy tradeEconomyInstance = ProgramContext.Instance.TradeEconomy;


            for (int i = 0; i < tradeEconomyInstance.Portfolios.Items.Count; i++)
            {
                if (tradeEconomyInstance.Portfolios[i].ID == portID)
                {
                    return tradeEconomyInstance.Portfolios[i];
                }
            }
            Debug.Assert(false, "Orders: No trader with ID could be found : " + portID);
            return null;
        }
        public static IDataItem GetDataItemByID(string myID)
        {
            ITradeEconomy tradeEconomyInstance = ProgramContext.Instance.TradeEconomy;



            for (int i = 0; i < tradeEconomyInstance.Portfolios.Items.Count; i++)
            {
                IPortfolio portf = tradeEconomyInstance.Portfolios[i];
                for (int j = 0; j < portf.DataItems.Count; j++)
                {
                    IDataItem di = portf.DataItems[j];
                    if (di.ID == myID)
                        return di;


                }
            }
            
            //Debug.Assert(false, "DataItem: No DataItem with ID could be found : " + myID);
            return null;

        }


        #endregion

        #region serialize

        public bool Serialize_OnlySimpleProperties()
        {
            if (base.Serialize())
            {
                return true;
            }
            return false;
        }
        public override bool Serialize()
        {
            try
            {
                this.ResetPathFromConfiguration();
                if (base.Serialize())
                {
                    if (this.traders != null)
                    {
                        this.traders.Serialize();


                    }
                    if (this.economyStatusCollection != null)
                    {
                        this.economyStatusCollection.Serialize();


                    }
                    if (this.tradeEconomyProfile != null)
                    {
                        this.tradeEconomyProfile.Serialize();
                    }
                    bool b = Serialize_DataClasses();
                    return b;

                }
                return false;
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show("Error serializing TradeEconomy " + ex.Message);
                return false;

            }


        }
        public bool Serialize_DataClasses()
        {
            if (portfolios != null)
            {
                for (int i = 0; i < this.portfolios.Items.Count; i++)
                {
                    IPortfolio actualPortfolio = this.portfolios[i] as IPortfolio;
                    actualPortfolio.Serialize_DataClasses();

                }
            }
            return true;
        }

        public override bool DeSerialize(ref object o)
        {
            try
            {
                object o1 = new TradeEconomy();
                ProgramContext pc = ProgramContext.Instance;
                pc.Logfile.WriteTimeSpanLog(" -- Deserializing TradeEconomy ");

                if (XMLSerializable.DeSerializeStatic(ref o1, this.path, this.iD))
                {
                    TradeEconomy te = o1 as TradeEconomy;

                    o = o1;
                    //get profile per ID:

                    CreateAdditionalEconomyData(te);
                    return true;


                }
                else
                {
                    //no deserialization - 
                    //System.Windows.Forms.MessageBox("Trade Economy not there - creating new one ...");
                    //TradeEconomy te = new TradeEconomy();
                    //CreateAdditionalEconomyData(te);

                    pc.Logfile.WriteTimeSpanLog(" ERROR - No economy present at : " + this.path + " with ID " + this.iD);
                    System.Diagnostics.Debug.WriteLine("No economy present " + this.iD);
                    //System.Windows.Forms.MessageBox.Show("Creating new trade economy " + this.iD);
                   // te.Serialize();

                    return false;

                    //Debug.Assert(false,"Error deserializing Economy " + this.iD);
                }
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error deserializing TradeEconomy " + ex.Message);
            }
            return false;


        }
        private static void CreateAdditionalEconomyData(ITradeEconomy te)
        {
            try
            {
                TradeEconomyProfileFactory tepf = new TradeEconomyProfileFactory();
                tepf.Create(te.ID);
                tepf.DeSerialize();
                te.TradeEconomyProfile = tepf.StockObjectBase as TradeEconomyProfile;
                //-----------------------------------
                //TradersFactory trf = new TradersFactory();
                //trf.Create(te.ID);
                ITraders mytraders = new Traders();
                mytraders.DeSerialize();

                //Debug.Assert(trf.DeSerialize());
                te.Traders = mytraders;
                //te.traders = new Traders();

                te.Portfolios = DeserializePortfolios(te);

                INewsCollection myNews = new NewsCollection();
                myNews.DeSerialize();
                te.NewsCollection = myNews;

                //DeserializeEconomyStatus(te);
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error CreateAdditionalEconomyData " + ex.Message);
            }


        }
        #endregion

        #region TradeEconomy simulation properties


        [Category("Trade\\Orders"), DescriptionAttribute("ClassInstance")]
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public ArrayList OrderAssetsSell
        {
            get
            {
                return this.orderAssetsSell;
            }
            set
            {
                this.orderAssetsSell = value;

            }
        }
        [Category("Trade\\Orders"), DescriptionAttribute("ClassInstance")]
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public ArrayList OrderAssetsBuy
        {
            get
            {
                return this.orderAssetsBuy;
            }
            set
            {
                this.orderAssetsBuy = value;

            }
        }
        [Category("Trade\\Orders"), DescriptionAttribute("ClassInstance")]
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public ArrayList OrderDepositSell
        {
            get
            {
                return this.orderDepositSell;
            }
            set
            {
                this.orderDepositSell = value;

            }
        }
        [Category("Trade\\Orders"), DescriptionAttribute("ClassInstance")]
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public ArrayList OrderDepositBuy
        {
            get
            {
                return this.orderDepositBuy;
            }
            set
            {
                this.orderDepositBuy = value;

            }
        }

        #endregion

        #region TradeEconomy simulation methods

        private static bool SortEconomyStatusCollection(IEconomyStatusCollection economyStatusCollection, EconomyStatusCollection newStatusCollection)
        {
            if (economyStatusCollection.Items.Count < 1)
                return false;

            DateTime dt = new DateTime(3000, 1, 1);
            int indexMin = 0;
            IEconomyStatus es = null;
            for (int i = 0; i < economyStatusCollection.Items.Count ; i++)
            {
                es = economyStatusCollection.Items[i] as IEconomyStatus;
                if (es.Date < dt)
                {
                    dt = es.Date;
                    indexMin = i;
                }
              
            }
            es = economyStatusCollection.Items[indexMin] as IEconomyStatus;
            newStatusCollection.Items.Add(es);
            economyStatusCollection.Items.RemoveAt(indexMin);
            SortEconomyStatusCollection(economyStatusCollection, newStatusCollection);

            //Debug.Assert(false, "SW error - while sorting economy status collection");
            return false;
        }


        private ITrader GetTrader_WhichSellsDepositID(string depositID)
        {
            if (depositID == this.iD)
                return this;

            if (this.deposits[depositID] != null)
                return this;

            for (int i = 0; i < this.traders.Items.Count; i++)
            {
                if (traders[i].Deposits[depositID] != null)
                {
                    return traders[i];
                }
            }
            Debug.Assert(false, "Orders: No owner of deposit with ID could be found : " + depositID);
            return null;
        }
        private static IAsset GetAssetByID(string myID, ITrader traderSell)
        {
            for (int i = 0; i < traderSell.Assets.Items.Count; i++)
            {
                IAsset ass = traderSell.Assets.Items[i] as IAsset;

                if (ass.ID == myID)
                {
                    return ass;
                }
            }
            Debug.Assert(false, "Orders: No asset with ID could be found : " + myID + " - for trader : " + traderSell.ID);
            return null;
        }


        private bool TradeSingleDeposit(IOrders ordersBuy)
        {


            for (int i = 0; i < ordersBuy.Count; i++)
            {
                IOrder myOrdBuy = ordersBuy[i] as IOrder;


                ITrader myTraderSell = GetTrader_WhichSellsDepositID(myOrdBuy.ID);
                ITrader myTraderBuy = this.traders[myOrdBuy.TraderID] as ITrader;
                IDeposit myDepToTrade = null;

                //buy a deposit from CB
                if (myOrdBuy.OrderType == OrderType.Buy_Deposit_CB)
                {
                    //myTraderSell = this;
                    if (myTraderBuy.Money_Current >= myOrdBuy.Bid)
                    {
                        IDeposit dep = CreateCentralBankDepost(myOrdBuy.Bid);
                        myTraderBuy.Money_Current -= myOrdBuy.Bid;
                        myTraderBuy.Deposits.Items.Add(dep);
                        break;
                    }
                    break;

                }
                //sell a deposit to CB
                if (myOrdBuy.OrderType == OrderType.Sell_Deposit_CB)
                {
                    myTraderSell = this.traders[myOrdBuy.TraderID] as ITrader;
                    myTraderBuy = this;

                    myDepToTrade = myTraderSell.Deposits[myOrdBuy.ID];
                    if (myDepToTrade != null)
                    {
                        myTraderSell.Deposits.Items.Remove(myDepToTrade);
                        myTraderSell.Money_Current += myDepToTrade.Value_Current;
                        myTraderBuy.Money_Current -= myDepToTrade.Value_Current;

                    }


                    break;


                }
                myDepToTrade = myTraderSell.Deposits[myOrdBuy.ID];
                //normal trade of deposit
                if (myDepToTrade != null && myTraderBuy != null && myTraderSell != null)
                {
                    //check if Buyer has enough money
                    double valTotal = myOrdBuy.NumberOfItems * myOrdBuy.Bid;
                    if (myTraderBuy.Money_Current > valTotal)
                    {

                        //trade!
                        myTraderBuy.Money_Current -= valTotal;
                        myTraderSell.Money_Current += valTotal;
                        Deposit depNew = myDepToTrade as Deposit;
                        depNew = depNew.Clone() as Deposit;
                        ((IDeposit)depNew).Number = myOrdBuy.NumberOfItems;
                        myTraderSell.Deposits.Items.Add(depNew);
                        myDepToTrade.Number -= myOrdBuy.NumberOfItems;
                        if (myDepToTrade.Number == 0)
                        {
                            myTraderSell.Deposits.Items.Remove(myDepToTrade);

                        }
                        //Debug.Assert(myDepToTrade.Number > -1, "Software error - number of deposits to sell is lower than 0!");



                    }


                }
                else
                {
                    Debug.Assert(false, "Deposit trade case not yet considered - fix!");
                }



            }
            return true;

        }
        private IDeposit CreateCentralBankDepost(double price)
        {
            IDeposit dep = new Deposit();
            //tradSell.Money_Current += price;
            //tradBuy.Money_Current -= price;
            dep.ValueBuy = price;
            dep.Value_Current = price;
            dep.DateBuy = this.date_Current;
            return dep;

        }
        private bool TradeSingleAsset(IOrders ordersBuy, IOrders ordersSell)
        {
            //get values 
            for (int i = 0; i < ordersSell.Count; i++)
            {
                IOrder myOrdSell = ordersSell[i] as IOrder;
                for (int j = 0; j < ordersBuy.Count; j++)
                {
                    IOrder myOrdBuy = ordersBuy[i] as IOrder;
                    if (myOrdBuy.ID == myOrdSell.ID)
                    {
                        if (myOrdSell.Bid <= myOrdBuy.Bid)
                        {
                            //order can be done!!
                            //price
                            double price = (myOrdSell.Bid + myOrdBuy.Bid) / 2;
                            ITrader tradBuy = GetTraderByID(myOrdBuy.TraderID);
                            ITrader tradSell = GetTraderByID(myOrdSell.TraderID);
                            if (tradSell == null || tradBuy == null)
                                return false;

                            IAsset myAsset = GetAssetByID(myOrdSell.ID, tradSell);
                            if (myAsset == null)
                                return false;

                            myAsset.OwnerID = tradBuy.ID;
                            if (myOrdSell.OrderType == OrderType.Sell_Asset_CB)
                            {
                                if (tradBuy == this)
                                {
                                    //CB buys asset and pays by deposit

                                    IDeposit dep = CreateCentralBankDepost(price);
                                    tradSell.Deposits.Items.Add(dep);


                                    //tradSell.Assets.Items.Remove(myAsset);


                                }
                                else
                                {
                                    if (tradBuy.Money_Current >= price)
                                    {
                                        //CB sells asset and creates cash money ...
                                        tradBuy.Money_Current -= price;
                                        this.money_Current += price;
                                        IDeposit dep = new Deposit();
                                        //tradSell.Money_Current += price;
                                        //tradBuy.Money_Current -= price;
                                        dep.ValueBuy = price;
                                        dep.Value_Current = price;
                                        dep.DateBuy = this.date_Current;


                                        //tradBuy.Deposits.Items.Add(dep);
                                    }
                                    else
                                    {
                                        //order cannot be done 
                                        break;
                                    }

                                }
                            }
                            else
                            {
                                //normal trade between traders
                                tradBuy.Money_Current -= price;
                                tradSell.Money_Current += price;



                                //remove orders

                            }
                            tradSell.Assets.Items.Remove(myAsset);
                            tradBuy.Assets.Items.Add(myAsset);
                            ordersBuy.Remove(myOrdBuy);
                            ordersSell.Remove(myOrdSell);

                            return true;




                        }
                    }
                }

            }

            return false;

        }
        private bool TradeAssetOrders()
        {

            //double moneySell = GetOrderValues(assetSell);
            //double moneyBuy = GetOrderValues(assetBuy);

            for (int i = 0; i < orderAssetsSell.Count; i++)
            {
                IOrders ordersSell = orderAssetsSell[i] as IOrders;
                for (int j = 0; j < orderAssetsBuy.Count; j++)
                {
                    IOrders ordersBuy = orderAssetsBuy[j] as IOrders;
                    if (ordersBuy.ID == ordersSell.ID)
                    {
                        TradeSingleAsset(ordersBuy, ordersSell);

                    }

                }
            }

            return true;
        }
        private bool TradeDepositOrders()
        {

            //double moneySell = GetOrderValues(assetSell);
            //double moneyBuy = GetOrderValues(assetBuy);

            for (int i = 0; i < orderDepositSell.Count; i++)
            {
                IOrders ordersSell = orderDepositSell[i] as IOrders;
                TradeSingleDeposit(ordersSell);
            }
            for (int i = 0; i < this.orderDepositBuy.Count; i++)
            {
                IOrders ordersBuy = orderDepositBuy[i] as IOrders;
                TradeSingleDeposit(ordersBuy);
            }

            return true;
        }
        private bool CreateNewQuotes()
        {
            for (int i = 0; i < this.portfolios.Items.Count; i++)
            {
                IPortfolio myPf = this.portfolios[i] as IPortfolio;
                for (int j = 0; j < myPf.DataItems.Count; j++)
                {
                    IDataItem di = myPf.DataItems[j] as IDataItem;
                    IDataClass dc = di.DataClass;
                    if (dc.BondType)
                    {
                        IEconomyStatus es = this.EconomyStatus_Current;

                        if (es == null)
                        {
                            //call with bond interest rate
                            dc.CreateNewQuote_Bond_FromInterestRate(this.date_Current, dc.BondInterestRate);

                        }
                        else
                        {
                            dc.CreateNewQuote_Bond_FromInterestRate(this.date_Current, es.Percentage_InterestCB);

                        }


                    }
                    else
                    {
                        dc.CreateNewQuoteFromLastTradedPrice(this.date_Current);
                    }


                }

            }


            return true;
        }
        private bool TradeStockOrders()
        {
            for (int i = 0; i < this.portfolios.Items.Count; i++)
            {
                IPortfolio myPf = this.portfolios[i] as IPortfolio;
                for (int j = 0; j < myPf.DataItems.Count; j++)
                {
                    IDataItem di = myPf.DataItems[j] as IDataItem;
                    IDataClass dc = di.DataClass;
                    if (dc.OrderStockSell.Count > 0 && dc.OrderStockBuy.Count > 0)
                    {
                        dc.TradeStockOrders();
                        //dc.CreateNewQuoteFromLastTradedPrice(this.date_Current);
                    }


                }

            }


            return true;
        }
        public bool TradeAll(int myDateIndex)
        {
            //int myDateIndex = myDataItem.DataClass.QuoteCollection.IndexOf(myDataItem.TradeStep.Date);

            SetAllOrdersFromTradeSystems(myDateIndex);

            TradeAssetOrders();
            TradeDepositOrders();
            TradeStockOrders();

            return true;
        }
        public DataTable StatusReport
        {
            get
            {
                return this.statusReport;
            }
        }
        public bool SetAssetsToTraders(IAssets ass)
        {
            for (int i = 0; i < ass.Items.Count; i++)
            {
                IAsset myAss = ass.Items[i] as IAsset;
                if (myAss.OwnerID == this.iD)
                {
                    this.assets.Items.Add(myAss);

                }
                else
                {
                    for (int j = 0; j < this.traders.Items.Count; j++)
                    {
                        ITrader trad = this.traders.Items[j] as ITrader;
                        if (myAss.OwnerID == trad.ID)
                        {
                            trad.Assets.Items.Add(myAss);
                            break;
                        }
                    }
                }

            }
            return true;

        }
        private bool SetStockOrdersToShares()
        {
            SetStockOrdersToShares(orderStocks);
            return true;

        }
        private bool SetStockOrdersToShares(IOrders orders)
        {

            for (int j = 0; j < this.traders.Items.Count; j++)
            {
                ITrader trad = this.traders.Items[j] as ITrader;
                trad.ShareBuyOrderValue = 0F;
            }


            for (int i = 0; i < orders.Count; i++)
            {
                IOrder myOrder = orders[i] as IOrder;
                //for(int i = 0; i < this.portfolios.Items.Count; i++)
                IDataClass dc = this.portfolios.GetDataClassByID(myOrder.ID);
                Debug.Assert(dc != null);
                if (dc != null)
                {
                    if (myOrder.OrderType == OrderType.Buy_Stock ||
                        myOrder.OrderType == OrderType.Buy_Bond)
                    {
                        //add onky if trader has enough money ...
                        ITrader trad = GetTraderByID(myOrder.TraderID);

                        if (trad == null)
                        {
                            Debug.Assert(trad != null, "Trader is not known ... " + trad.ID);
                            System.Windows.Forms.MessageBox.Show("Could not add share order : " + myOrder.ID + " - for trader " + trad.ID + " - not enough money ");
                            break;

                        }
                        else
                        {

                            trad.ShareBuyOrderValue += myOrder.Bid * myOrder.NumberOfItems;
                            if (trad.ShareBuyOrderValue > trad.Money_Current)
                            {
                                trad.ShareBuyOrderValue -= myOrder.Bid * myOrder.NumberOfItems;
                                System.Windows.Forms.MessageBox.Show("Could not add share order : " + myOrder.ID + " - for trader " + trad.ID + " - not enough money ");
                            }
                            else
                            {
                                dc.OrderStockBuy.Add(myOrder);
                            }
                        }






                    }
                    else
                    {
                        dc.OrderStockSell.Add(myOrder);
                    }
                }



            }


            return true;

        }
        public bool SetDepositsToTraders(IDeposits ass)
        {
            for (int i = 0; i < ass.Items.Count; i++)
            {
                IDeposit myAss = ass.Items[i] as IDeposit;
                if (myAss.OwnerID == this.iD)
                {
                    this.deposits.Items.Add(myAss);

                }
                else
                {
                    for (int j = 0; j < this.traders.Items.Count; j++)
                    {
                        ITrader trad = this.traders.Items[j] as ITrader;
                        if (myAss.OwnerID == trad.ID)
                        {
                            trad.Deposits.Items.Add(myAss);
                            break;
                        }
                    }
                }

            }
            return true;

        }
        public bool SetAllOrdersFromTradeSystems(int myDateIndex)
        {
            for (int i = 0; i < this.traders.Items.Count; i++)
            {
                ITrader trad = this.traders.Items[i] as ITrader;
                trad.SetMyOrdersFromTradeSystems(myDateIndex, this.date_Current, false);


            }
            return true;

        }
        public bool FirstInitIndicators_All()
        {
            for (int i = 0; i < this.traders.Items.Count; i++)
            {
                ITrader trad = this.traders.Items[i] as ITrader;
                FirstInitIndicators(trad);


            }
            return true;
        }

        public bool AddStatusReportItem()
        {
            try
            {
                if (this.StatusReport == null)
                    this.CreateStatusReportBase();


                //int i = this.statusReport.Row

                DataRow dr = statusReport.NewRow();

                //overall:
                int ind = 0;
                dr[0 + ind * 5] = " ";
                dr[1 + ind * 5] = this.date_Current;

                dr[2 + ind * 5] = this.Overall_Value_Total;
                dr[3 + ind * 5] = this.Overall_Money_Current;
                dr[4 + ind * 5] = this.Overall_Value_Assets;
                dr[5 + ind * 5] = this.Overall_Value_Deposits;
                dr[6 + ind * 5] = this.Overall_Value_Shares;

                //TradeEconomy
                ind = 1;

                dr[2 + ind * 5] = this.Value_Total;
                dr[3 + ind * 5] = this.money_Current;
                dr[4 + ind * 5] = this.Value_Assets;
                dr[5 + ind * 5] = this.Value_Deposits;
                dr[6 + ind * 5] = this.Value_Shares;


                for (int i = 0; i < this.traders.Items.Count; i++)
                {
                    ITrader trad = this.traders.Items[i] as ITrader;
                    dr[2 + (i + 2) * 5] = trad.Value_Total;
                    dr[3 + (i + 2) * 5] = trad.Money_Current;
                    dr[4 + (i + 2) * 5] = trad.Value_Assets;
                    dr[5 + (i + 2) * 5] = trad.Value_Deposits;
                    dr[6 + (i + 2) * 5] = trad.Value_Shares;

                }
                statusReport.Rows.Add(dr);
                return true;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error adding status report item: " + ex.Message);
                return false;

            }



        }
        public bool AddOrderBookItem()
        {
            try
            {
                if (this.orderBookTable == null)
                    this.CreateOrderBookBase();


                DataRow dr = statusReport.NewRow();

                //overall:
                int ind = 0;
                dr[0 + ind * 5] = " ";
                dr[1 + ind * 5] = this.date_Current;

                dr[2 + ind * 5] = this.Overall_Value_Total;
                dr[3 + ind * 5] = this.Overall_Money_Current;
                dr[4 + ind * 5] = this.Overall_Value_Assets;
                dr[5 + ind * 5] = this.Overall_Value_Deposits;
                dr[6 + ind * 5] = this.Overall_Value_Shares;

                //TradeEconomy
                ind = 1;

                dr[2 + ind * 5] = this.Value_Total;
                dr[3 + ind * 5] = this.money_Current;
                dr[4 + ind * 5] = this.Value_Assets;
                dr[5 + ind * 5] = this.Value_Deposits;
                dr[6 + ind * 5] = this.Value_Shares;


                this.orderBookTable.Rows.Add(dr);
                return true;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error adding orderbook item: " + ex.Message);
                return false;

            }



        }

        public bool Empty_All()
        {
            string id = "CentralBank";
            //DeleteOldOne();
            this.iD = id;


            this.Money_Initial = 0;



            //-------------------------------------------------
            //profile
            TradeEconomyProfileFactory tpf = new TradeEconomyProfileFactory();
            this.TradeEconomyProfile = (ITradeEconomyProfile)(tpf.StockObjectBase);

            //-------------------------------------------------
            //traders
            TradersFactory tf = new TradersFactory();
            this.traders = tf.StockObjectBase as ITraders;

            //-------------------------------------------------
            //Portfolios
            PortfoliosFactory pf = new PortfoliosFactory();
            pf.Create_Default();
            pf.Portfolios.Create_Default();

            this.portfolios = pf.Portfolios;


            //Debug.Assert(false, "Not implemented");
            return true;
        }

        public bool AddOneDay()
        {


            DateTime dt = this.Date_Current.AddDays(1);
            this.Date_Current = dt;
            this.dateIndex += 1;

            //SetTradeOrdersForEconomyBunds();

            SetTradeOrdersForEconomyBunds();

            this.TradeAll(dateIndex);
            CreateNewQuotes();


            AddStatusReportItem();

            return true;
        }
        public bool CreateOrderColections(IOrders orderCollection)
        {
            //create all order types


            for (int i = 0; i < orderCollection.Count; i++)
            {
                IOrder ord = orderCollection[i] as IOrder;

                switch (ord.OrderType)
                {
                    case OrderType.Buy_Asset:
                        {
                            AddOrder(orderAssetsBuy, ord);
                            break;
                        }
                    case OrderType.Sell_Asset:
                        {
                            AddOrder(orderAssetsSell, ord);

                            break;
                        }
                    case OrderType.Buy_Deposit:
                        {
                            AddOrder(orderDepositBuy, ord);

                            break;
                        }
                    case OrderType.Sell_Deposit:
                        {
                            AddOrder(orderDepositSell, ord);
                            break;
                        }
                    case OrderType.Buy_Stock:
                        {
                            this.orderStocks.Add(ord);

                            break;
                        }
                    case OrderType.Sell_Stock:
                        {
                            this.orderStocks.Add(ord);
                            break;
                        }
                    case OrderType.Buy_Bond:
                        {
                            this.orderStocks.Add(ord);

                            break;
                        }
                    case OrderType.Sell_Bond:
                        {
                            this.orderStocks.Add(ord);
                            break;
                        }
                    case OrderType.Buy_Asset_CB:
                        {
                            AddOrder(orderAssetsBuy, ord);
                            break;
                        }
                    case OrderType.Sell_Asset_CB:
                        {
                            AddOrder(orderAssetsSell, ord);

                            break;
                        }
                    case OrderType.Buy_Deposit_CB:
                        {
                            AddOrder(orderDepositBuy, ord);

                            break;
                        }
                    case OrderType.Sell_Deposit_CB:
                        {
                            AddOrder(orderDepositSell, ord);
                            break;
                        }

                    default:
                        {
                            System.Windows.Forms.MessageBox.Show("Order type not set !");
                            break;
                        }





                }


            }
            this.SetStockOrdersToShares();

            return true;
        }
        private static bool AddOrder(System.Collections.ArrayList arrListIn, IOrder myOrder)
        {
            string myid = myOrder.ID;

            for (int i = 0; i < arrListIn.Count; i++)
            {
                IOrders myorders = arrListIn[i] as IOrders;
                if (myorders.ID == myid)
                {
                    myorders.Add(myOrder);
                    return true;
                }
            }
            IOrders myordersNew = new Orders();
            myordersNew.ID = myid;
            myordersNew.Add(myOrder);

            arrListIn.Add(myordersNew);

            return false;

        }

        public void CreateStatusReportBase()
        {
            statusReport = new DataTable("StatusReport");

            statusReport.Columns.Add("Index");
            statusReport.Columns.Add("Date");
            int ind = -1;
            for (int i = 0; i < this.traders.Items.Count + 2; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    ind++;
                    statusReport.Columns.Add(ind.ToString());
                }
            }




            DataRow dr = statusReport.NewRow();
            dr[0] = " ";
            dr[1] = " ";
            dr[2] = "Overall";
            dr[7] = "CentralBank";

            for (int i = 0; i < this.traders.Items.Count; i++)
            {
                ITrader trad = this.traders.Items[i] as ITrader;
                dr[2 + (i + 2) * 5] = trad.ID;

            }

            statusReport.Rows.Add(dr);

            dr = statusReport.NewRow();
            dr[0] = " ";
            dr[1] = "Date";
            for (int i = 0; i < this.traders.Items.Count + 2; i++)
            {
                dr[2 + i * 5] = "Total";
                dr[3 + i * 5] = "Money";
                dr[4 + i * 5] = "Assets";
                dr[5 + i * 5] = "Deposits";
                dr[6 + i * 5] = "Shares";
            }

            statusReport.Rows.Add(dr);






        }
        public void CreateOrderBookBase()
        {
            orderBookTable = new DataTable("OrderBook");

            statusReport.Columns.Add("DataClassID");
            statusReport.Columns.Add("TraderID");
            statusReport.Columns.Add("DateOrder");
            statusReport.Columns.Add("DateDue");
            statusReport.Columns.Add("DateOrder");
            statusReport.Columns.Add("NumberOfItems");
            statusReport.Columns.Add("Bid");
            statusReport.Columns.Add("OrderType");





            //DataRow dr = statusReport.NewRow();
            //dr[0] = " ";
            //dr[1] = " ";
            //dr[2] = "Overall";
            //dr[7] = "CentralBank";

            //statusReport.Rows.Add(dr);






        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public double Overall_Money_Current
        {
            get
            {
                double val = this.money_Current;
                if (this.traders == null || this.traders.Items.Count == 0)
                    return val;
                for (int i = 0; i < this.traders.Items.Count; i++)
                {
                    ITrader myTrad = this.traders.Items[i] as ITrader;
                    val += myTrad.Money_Current;
                }
                return val;
            }

        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public double Overall_Value_Assets
        {
            get
            {
                double val = this.Value_Assets;
                if (this.traders == null || this.traders.Items.Count == 0)
                    return val;
                for (int i = 0; i < this.traders.Items.Count; i++)
                {
                    ITrader myTrad = this.traders.Items[i] as ITrader;
                    val += myTrad.Value_Assets;
                }
                return val;
            }

        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public double Overall_Value_Deposits
        {
            get
            {
                double val = this.Value_Deposits;
                if (this.traders == null || this.traders.Items.Count == 0)
                    return val;
                for (int i = 0; i < this.traders.Items.Count; i++)
                {
                    ITrader myTrad = this.traders.Items[i] as ITrader;
                    val += myTrad.Value_Deposits;
                }
                return val;
            }

        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public double Overall_Value_Total
        {
            get
            {
                double val = Overall_Value_Shares + Overall_Value_Deposits + Overall_Value_Assets + Overall_Money_Current;
                return val;

            }

        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public double Overall_Value_Shares
        {
            get
            {
                double val = this.Value_Shares;
                if (this.traders == null || this.traders.Items.Count == 0)
                    return val;
                for (int i = 0; i < this.traders.Items.Count; i++)
                {
                    ITrader myTrad = this.traders.Items[i] as ITrader;
                    val += myTrad.Value_Shares;
                }
                return val;
            }

        }
        public static IDataClass GetShareByID(string name)
        {
            ITradeEconomy te = ProgramContext.Instance.TradeEconomy;
            for (int iportf = 0; iportf < te.Portfolios.Items.Count; iportf++)
            {
                IPortfolio portf = te.Portfolios.Items[iportf] as IPortfolio;

                for (int i = 0; i < portf.DataItems.Count; i++)
                {
                    IDataItem di = portf.DataItems[i] as DataItem;
                    if (di.ID == name)
                    {
                        return di.DataClass;
                    }

                }
            }
            return null;

        }
        private static bool InitInds(ITradeSystem ts)
        {
            if (ts == null)
                return false;
            IPortfolio myPortf = TradeEconomy.GetPortfolioByID(ts.PortfolioID);
            Debug.Assert(myPortf != null, "Portfolio is not there ");
            if (myPortf != null)
            {
                IDataClass dc = myPortf.GetShareByID(ts.ShareID);
                Debug.Assert(dc != null, "Portfolio is not there ");

                if (dc != null)
                {
                    IIndicators inds = Indicators.UpdateForTradeSystem(false, dc, ts);
                    if (inds != null)
                    {
                        for (int i = 0; i < inds.Count; i++)
                        {
                            IIndicator ind = inds[i];
                            IIndicators myDCInds = dc.IndicatorsUnchecked;
                            if (!myDCInds.Contains(ind))
                            {
                                myDCInds.Add(ind);
                            }
                            dc.IndicatorsJustGetEm = myDCInds;

                        }
                    }

                    //test
                    //IIndicators indsNew = dc.IndicatorsChecked;
                }

            }
            return true;

        }
        private static bool FirstInitIndicators(ITrader myTrader)
        {
            ITradeSystem ts = myTrader.TradeSystem1;
            InitInds(ts);


            ts = myTrader.TradeSystem2;
            InitInds(ts);

            ts = myTrader.TradeSystem3;
            InitInds(ts);

            ts = myTrader.TradeSystem4;
            InitInds(ts);

            return true;


        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public IEconomyStatusCollection EconomyStatusCollection
        {
            get
            {
                if (economyStatusCollection == null)
                {
                    economyStatusCollection = new EconomyStatusCollection();
                    economyStatusCollection.DeSerialize();
                }
                return economyStatusCollection;
            }
            set
            {

                economyStatusCollection = value;
            }

        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public EconomyStatus[] EconomyStatusArray
        {
            get
            {


                if (this.economyStatusCollection != null)
                {
                    EconomyStatusCollection myeconomyStatusCollection = economyStatusCollection as EconomyStatusCollection;
                    //System.Collections.ArrayList arrL = new System.Collections.ArrayList();
                    return (EconomyStatus[])myeconomyStatusCollection.Items.ToArray(typeof(EconomyStatus));
                }

                return null;
            }
            set
            {

                economyStatusCollection = new EconomyStatusCollection();
                for (int i = 0; i < value.Length; i++)
                {
                    EconomyStatus q = value[i] as EconomyStatus;

                    this.economyStatusCollection.Items.Add(q);

                }

            }
        }
        private IPortfolio GetBondsPortfolio()
        {
            for (int i = 0; i < this.portfolios.Items.Count; i++)
            {
                IPortfolio portf = this.portfolios.Items[i] as IPortfolio;
                if (portf.Name == "Bonds")
                {
                    return portf;
                }
            }
            return null;
        }

        public bool SetTradeOrdersForEconomyBunds()
        {

            IPortfolio portf = GetBondsPortfolio();
            if (portf == null)
                return false;

            for (int i = 0; i < portf.DataItems.Count; i++)
            {
                IDataItem di = portf.DataItems[i] as IDataItem;
                IDataClass dc = di.DataClass;

                //remove all older orders
                dc.OrderStockBuy = new Orders();
                dc.OrderStockSell = new Orders();


                double lastQuote = dc.QuoteCurrent;
                IIndicator myInd = dc.IndicatorsChecked["InterestCB" + "_2"];
                double targetInterest = myInd.ValuesFloat[myInd.ValuesFloat.Count - 1];
                double currentYield = dc.BondYield;
                double diffInPercent = (currentYield - targetInterest) * 100 / currentYield;

                //1. compare with margin

                //yield > interest rate -> it makes sense to buy since more interest expected
                if (diffInPercent <= this.marginInterestSell)
                {
                    double price = lastQuote * (1 - this.marginBidSell);
                    //bidMoreOrLessInPercentForBonds
                    //calculate price for selling
                    CreateNewOrder("SELL", price, di.Number, dc);
                }
                else if (diffInPercent >= this.marginInterestBuy)
                {
                    double price = lastQuote * (1 + this.marginBidBuy);
                    //bidMoreOrLessInPercentForBonds
                    //calculate price for selling
                    int number = Convert.ToInt32(this.Money_Current / price);
                    CreateNewOrder("BUY", price, number, dc);
                }

                //----------------------
                if (this.EconomyStatus_Current.BondsSell)
                {
                    double price = lastQuote;
                    //bidMoreOrLessInPercentForBonds
                    //calculate price for selling
                    CreateNewOrder("SELL", price, di.Number, dc);
                }
                if (this.EconomyStatus_Current.BondsBuy)
                {
                    double price = lastQuote;
                    //bidMoreOrLessInPercentForBonds
                    //calculate price for selling
                    int number = Convert.ToInt32(this.Money_Current / price);
                    CreateNewOrder("BUY", price, number, dc);
                }


                //dc.BondExpiryDate

            }

            return true;

        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public INewsCollection NewsCollection
        {
            get
            {


                return newsCollection;
            }
            set
            {

                newsCollection = value;
            }
        }

        public string ExcelFileName
        {
            get
            {


                return excelFileName;
            }
            set
            {

                excelFileName = value;
            }
        }

        public NewsCollection[] NewsArray
        {
            get
            {

                try
                {


                    if (this.newsCollection != null && newsCollection.Items != null && newsCollection.Items.Count > 0)
                    {
                        NewsCollection myNewsCollection = newsCollection as NewsCollection;


                        return (NewsCollection[])myNewsCollection.Items.ToArray(typeof(News));
                    }
                }
                catch (Exception ex)
                {
                    Debug.Assert(false, "Error getting news " + ex.Message);
                    return null;
                }

                return null;
            }
            set
            {

                newsCollection = new NewsCollection();
                for (int i = 0; i < value.Length; i++)
                {
                    object o = value[i];
                    News q = o as News;

                    this.newsCollection.Items.Add(q);

                }

            }
        }
        #endregion

        #region old

        public bool CreateShareData_FromDateStart(int numberOfDays)
        {


            //TradeEconomyFactory tef = new TradeEconomyFactory();



            //DataClassFactory dcf = new DataClassFactory();
            for (int i = 0; i < this.portfolios.Items.Count; i++)
            {
                IPortfolio portf = this.portfolios[i];
                //System.Collections.ArrayList moneyCollection = tef.CreateMoneyCollection(portf.Money, portf.DataItems.Count);

                for (int j = 0; j < portf.DataItems.Count; j++)
                {
                    IDataClass dc = portf.DataItems[j].DataClass;
                    IDataItem di = portf.DataItems[j];
                    double start = di.PriceFirst;

                    DateTime dt = this.date_Start;
                    DateTime dateTimeLoop = dt.AddDays(-1);

                    if (dc.QuoteCollection != null && dc.QuoteCollection.Count > 0)
                    {
                        start = dc.QuoteCollection[dc.QuoteCollection.Count - 1].CLOSEc;
                        dt = dc.QuoteCollection[dc.QuoteCollection.Count - 1].DATE;
                    }




                    for (int k = 0; k < numberOfDays; k++)
                    {
                        dateTimeLoop.AddDays(1);
                        DataClassFactory.Create_Quote_Random(dc, ref start, dateTimeLoop, 2);
                    }
                    dc.Serialize();

                    //dcf.Create_Quote_Random(dc, 

                }
                //have to update this
                //this.Date_Current = dt;

                //Create_Quote_Random(this.dataClassDaily, ref start, randomPercentage))

                //ITrader trad = this.traders[i] as ITrader;
                //trad.SetOrders();



            }
            return true;
        }

        #endregion


    }
}
